﻿using Autofac.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace FileManagerSystem.Extend
{
    /// <summary>
    /// 功能描述: NetCore依赖注入相关拓展
    /// </summary>
    public static class CoreIocExtend
    {
        /// <summary>
        /// Ioc服务容器
        /// </summary>
        private static IServiceProvider serviceProvider;

        /// <summary>
        /// 获取应用的服务容器IserviceProvider
        /// </summary>
        /// <param name="app"></param>
        public static void GetServiceProvider(this IApplicationBuilder app)
        {
            serviceProvider = app.ApplicationServices;
        }

        /// <summary>
        /// 从容器获取对应的服务
        /// 备注：如果没有找到对应的服务，则返回Null
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetService<T>()
        {
            var newScope = serviceProvider.CreateScope();
            return newScope != null ? newScope.ServiceProvider.GetService<T>() : serviceProvider.GetService<T>();
        }


        /// <summary>
        /// 从容器获取对应的服务
        /// 备注:没有找到对应的服务，则抛出InvalidOperationException异常
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetRequiredService<T>()
        {
            var newScope = serviceProvider.CreateScope();
            return (newScope != null ? newScope.ServiceProvider.GetRequiredService<T>() : serviceProvider.GetRequiredService<T>());
        }
    }

    /// <summary>
    /// 必须显式的注明Attribute为Autowired，才表示是属性注入的对象，便于开发时区分注入对象和普通对象
    /// </summary>
    public class AutowiredPropertySelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            return propertyInfo.CustomAttributes.Any(it => it.AttributeType == typeof(AutowiredAttribute));
        }
    }

    /// <summary>
    /// 显式的注明Attribute为Autowired，表示是属性注入的对象
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class AutowiredAttribute : Attribute
    {
    }
}
